package org.example.route.service.impl;

import org.example.route.constant.SeatConstant;
import org.example.route.constant.TrainConstant;
import org.example.route.mapper.CarriageMapper;
import org.example.route.mapper.SeatMapper;
import org.example.route.mapper.StationRouteMapper;
import org.example.route.mapper.TrainMapper;
import org.example.route.model.dto.*;
import org.example.route.model.pojo.Carriage;
import org.example.route.model.pojo.Seat;
import org.example.route.model.pojo.Train;
import org.example.route.model.vo.CarriageVO;
import org.example.route.model.vo.SeatShowVO;
import org.example.route.model.vo.TrainVO;
import org.example.route.service.TrainService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class TrainServiceImpl implements TrainService {
    @Autowired
    private TrainMapper trainMapper;
    @Autowired
    private CarriageMapper carriageMapper;
    @Autowired
    private SeatMapper seatMapper;
    @Autowired
    private StationRouteMapper stationRouteMapper;

    @Override
    @Transactional
    public void add(TrainDTO trainDTO)
    {
        Train train = new Train();
        BeanUtils.copyProperties(trainDTO,train);
        train.setStatus(TrainConstant.STATUS_WAIT);
        trainMapper.add(train);
        TrainCarriageDTO trainCarriageDTO = new TrainCarriageDTO();
        BeanUtils.copyProperties(trainDTO,trainCarriageDTO);
        trainCarriageDTO.setId(train.getId());
        addCarriage(trainCarriageDTO);
    }

    @Override
    public List<TrainVO> list(TrainQueryDTO trainQueryDTO) {
        List<TrainVO> trainVOList = new ArrayList<>();

        List<Train> trainList = trainMapper.list(trainQueryDTO);
        for (Train train : trainList) {
            String kindName = "";
            String statusName = "";

            if (train.getKind().equals(TrainConstant.KIND_BULLET)) {
                kindName = "动车";
            } else if (train.getKind().equals(TrainConstant.KIND_ORDINARY)) {
                kindName = "普通列车";
            } else if (train.getKind().equals(TrainConstant.KIND_HIGH_SPEED)) {
                kindName = "高铁";
            } else {
                kindName = "未知";
            }
            if (train.getStatus().equals(TrainConstant.STATUS_RUNNING)) {
                statusName = "正在运行";

            } else if (train.getStatus().equals(TrainConstant.STATUS_STOPPED)) {
                statusName = "停止运营";
            } else if (train.getStatus().equals(TrainConstant.STATUS_WAIT)) {
                statusName = "空闲状态";
            } else {
                statusName = "未知";
            }

            Long carriageCount= formCarriageCount(train.getId());
            System.out.println("==============================" + carriageCount);

            TrainVO trainVO = new TrainVO(train.getId(), train.getSerialNumber(), train.getKind(), kindName, train.getStatus(),statusName,carriageCount);
            trainVOList.add(trainVO);
        }

        return trainVOList;
    }


    @Override
    public void changeStatus(TrainChangeStatusDTO trainChangeStatusDTO) {
        trainMapper.changeStatus(trainChangeStatusDTO);
        //TODO在这里添加车站运行逻辑
    }

    @Override
    @Transactional
    public void addCarriage(TrainCarriageDTO trainCarriageDTO) {
        if(trainCarriageDTO.getKind().equals(TrainConstant.KIND_BULLET) ||
                trainCarriageDTO.getKind().equals(TrainConstant.KIND_HIGH_SPEED))
        {   //表明此车是高铁或者动车
            Long i = 0L;
            Long j = 0L;
            Long k = 0L;
            for (;i < trainCarriageDTO.getSeniorCount(); i++)
            {
               addHighSpeedOrDynamicCarriage(i + 1, trainCarriageDTO.getId(), TrainConstant.Carriage_Senior);
            }

            for (; j < trainCarriageDTO.getMiddleCount(); j++)
            {
                addHighSpeedOrDynamicCarriage(i + 1 + j, trainCarriageDTO.getId(), TrainConstant.Carriage_Middle);
            }

            for (; k < trainCarriageDTO.getLowCount(); k++)
            {
                addHighSpeedOrDynamicCarriage(i + 1 + j + k, trainCarriageDTO.getId(), TrainConstant.Carriage_Low);
            }

        }else {
            Long i = 0L;
            Long j = 0L;
            Long k = 0L;
            for (;i < trainCarriageDTO.getSeniorCount(); i++)
            {
                addOrdinaryCarriage(i + 1, trainCarriageDTO.getId(), TrainConstant.Carriage_Senior);
            }

            for (; j < trainCarriageDTO.getMiddleCount(); j++)
            {
                addOrdinaryCarriage(i + 1 + j, trainCarriageDTO.getId(), TrainConstant.Carriage_Middle);
            }

            for (; k < trainCarriageDTO.getLowCount(); k++)
            {
                addOrdinaryCarriage(i + 1 + j + k, trainCarriageDTO.getId(), TrainConstant.Carriage_Low);
            }

        }
    }




    //添加车厢方法的具体解耦
    //添加动车和高铁的车厢
    public void addHighSpeedOrDynamicCarriage(Long number, Long trainId,Long kindCarriage)
    {
         if(kindCarriage.equals(TrainConstant.Carriage_Senior))
         {
             //商务座只有五个座位
             Long volume = 5L;
             Carriage c = new Carriage(null,trainId,number,volume, volume);
             carriageMapper.add(c);
             for (Long i = 0L; i < volume; i++)
             {
                 //安装座位
                 seatMapper.add(new Seat(null,c.getId(), SeatConstant.UN_OCCUPY,i + 1,1L));
             }


         }
         else if(kindCarriage.equals(TrainConstant.Carriage_Middle))
         {
             //一等座有20个座位
             Long volume = 28L;
             Carriage c = new Carriage(null,trainId,number,volume, volume);
             carriageMapper.add(c);
             for (Long i = 0L; i < volume; i++)
             {
                 //安装座位
                 seatMapper.add(new Seat(null,c.getId(), SeatConstant.UN_OCCUPY,i + 1,4L));
             }


         }
         else if(kindCarriage.equals(TrainConstant.Carriage_Low))
         {
             //二等座有90个座位
             Long volume = 90L;
             Carriage c = new Carriage(null,trainId,number,volume, volume);
             carriageMapper.add(c);
             for (Long i = 0L; i < volume; i++)
             {
                 //安装座位
                 seatMapper.add(new Seat(null,c.getId(), SeatConstant.UN_OCCUPY,i + 1,5L));
             }
         }

    }

    //添加普通列车的车厢
    public void addOrdinaryCarriage(Long number,Long trainId, Long kindCarriage)
    {
        if(kindCarriage.equals(TrainConstant.Carriage_Senior))
        {
            //软卧只有36个铺位，每个包厢有4个床位
            Long volume = 36L;
            Carriage c = new Carriage(null,trainId,number,volume, volume);
            carriageMapper.add(c);
            for (Long i = 0L; i < volume; i++)
            {
                //安装座位
                seatMapper.add(new Seat(null,c.getId(), SeatConstant.UN_OCCUPY,i + 1,4L));
            }


        }
        else if(kindCarriage.equals(TrainConstant.Carriage_Middle))
        {
            //硬卧有66个铺位，每个包厢有6个
            Long volume = 66L;
            Carriage c = new Carriage(null,trainId,number,volume, volume);
            carriageMapper.add(c);
            for (Long i = 0L; i < volume; i++)
            {
                //安装座位
                seatMapper.add(new Seat(null,c.getId(), SeatConstant.UN_OCCUPY,i + 1,6L));
            }


        }
        else if(kindCarriage.equals(TrainConstant.Carriage_Low))
        {
            //硬座有110个座位，每个座位有5人
            Long volume = 110L;
            Carriage c = new Carriage(null,trainId,number,volume, volume);
            carriageMapper.add(c);
            for (Long i = 0L; i < volume; i++)
            {
                //安装座位
                seatMapper.add(new Seat(null,c.getId(), SeatConstant.UN_OCCUPY,i + 1,5L));
            }
        }

    }

    @Override
    public List<SeatShowVO> listTheSeat(SeatShowDTO seatShowDTO) {
        Long trainId = seatShowDTO.getTrainId();
        Long carriageNumber = seatShowDTO.getCarriageNumber();
        Carriage carriage = carriageMapper.getByTrainIdAndCarriageNumber(trainId,carriageNumber);
        List<Seat> seats = seatMapper.listByCarriageId(carriage.getId());
        return seats.stream().map(seat ->
                {
                    SeatShowVO seatShowVO = new SeatShowVO();
                    BeanUtils.copyProperties(seat,seatShowVO);
                    return seatShowVO;
                }).collect(Collectors.toList());
    }


    @Override
    public void delete(BaseRequest baseRequest) {
        //如果关联路线，就不能删除
        if (!stationRouteMapper.getByTrainId(Long.parseLong(baseRequest.getKey())).isEmpty()){

            throw new RuntimeException("该车次有路线关联，不能删除");
        }


        List<Long> carriageIds = carriageMapper.getIdsByTrainId(Long.parseLong(baseRequest.getKey()));

        //TODO 删除座位
        deleteSeats(carriageIds);

        //TODO 删除车厢
        deleteCarriages(Long.parseLong(baseRequest.getKey()));

        //先删除相应的车厢和座位
        trainMapper.delete(Long.parseLong(baseRequest.getKey()));



    }


    @Override
    @Transactional
    public void update(TrainDTO trainDTO) {
        //如果关联路线，就不能删除
        if (!stationRouteMapper.getByTrainId(trainDTO.getId()).isEmpty()){
            throw new RuntimeException("该车次有路线关联，不能删除");
        }

        //先删除车厢和座位
        List<Long> carriageIds = carriageMapper.getIdsByTrainId(trainDTO.getId());

        deleteSeats(carriageIds);
        deleteCarriages(trainDTO.getId());

        Train train = new Train();
        BeanUtils.copyProperties(trainDTO,train);

        trainMapper.update(train);

        //添加新车厢
        TrainCarriageDTO trainCarriageDTO = new TrainCarriageDTO();
        BeanUtils.copyProperties(trainDTO,trainCarriageDTO);
        trainCarriageDTO.setId(train.getId());
        addCarriage(trainCarriageDTO);


    }

    /**
     *
     *
     * 删除车厢
     *
     * **/

    void deleteCarriages(Long trainId)
    {
        carriageMapper.deleteByTrainId(trainId);

    }

    /**
     *
     *
     * 删除座位
     *
     * **/

    void deleteSeats(List<Long> carriageIds){

        seatMapper.deleteByCarriageIds(carriageIds);

    }




    /**
     *
     * 获得列车的车厢消息
     *
     *
     * **/
    private Long formCarriageCount(Long trainId) {
          Long carriageCount = carriageMapper.getCarriageCountById(trainId);
          return carriageCount;
    }


    @Override
    public List<CarriageVO> listCarriageByTrain(TrainGradeDTO trainGradeDTO) {
        Train train = trainMapper.getById(trainGradeDTO.getTrainId());
        if (Objects.isNull( train)){
            throw new RuntimeException("没有此车次");
        }


        Integer volume = 0;
        if (trainGradeDTO.getGrade().equals(TrainConstant.Carriage_Senior)){
            volume = train.getKind().equals(TrainConstant.KIND_ORDINARY)  ? 36 : 5;
        }else if (trainGradeDTO.getGrade().equals(TrainConstant.Carriage_Middle)){
            volume = train.getKind().equals(TrainConstant.KIND_ORDINARY)  ? 66 : 28;
        }else {
            volume = train.getKind().equals(TrainConstant.KIND_ORDINARY)  ? 110 : 90;
         }

        List<Carriage> carriageList = carriageMapper.listByTrainIdAndGrade(train.getId(), volume);
        return carriageList.stream().map(carriage ->
        {
            CarriageVO carriageVO = new CarriageVO();
            BeanUtils.copyProperties(carriage,carriageVO);
            return carriageVO;
        }).collect(Collectors.toList());


    }
}
